﻿import std.stdio: writefln;
import derelict.sdl.sdl;
import Point;
import Pixels;
import Utils;
import maths.Vec;
import maths.Matrix;

public class FloodFill {
	point[] points;
	point p;
	

	this(point p){
		this.p = p;
	}

	void fill(SDL_Surface *surface){
			point pkt;
			uint *pp = cast(uint*)surface.pixels;
			points ~= p;
			putPixel(surface, p, foreground);
			// writefln("foo");

			while(points.length > 0){
				pkt = points[$-1];
				points.length = points.length - 1;
				if(pp[pkt.x - 1 + xResolution*pkt.y] == background && pkt.x > 0){
					points ~= point(pkt.x - 1, pkt.y);
					putPixel(surface, points[$-1], foreground);
				}
				if(pp[pkt.x + 1 + xResolution*pkt.y] == background && pkt.x < xResolution - 1){
					points ~= point(pkt.x + 1, pkt.y);
					putPixel(surface, points[$-1], foreground);
				}	
				if(pp[pkt.x  + xResolution*(pkt.y - 1)] == background && pkt.y > 0){
					points ~= point(pkt.x , pkt.y -1);
					putPixel(surface, points[$-1], foreground);
				}
				if(pp[pkt.x  + xResolution*(pkt.y + 1)] == background ){
					if(pkt.y < yResolution - 2)
					points ~= point(pkt.x , pkt.y +1);
					putPixel(surface, pkt.x, pkt.y+1, foreground);
				}				
			}
	}

	void fill(SDL_Surface *surface, SDL_Surface *bitmap, point ps, mat4 invert, bool interpolation){
			p = ps;
			point pkt;
			uint *pp = cast(uint*)surface.pixels;
			points ~= p;
			putPixel(surface, p, getPixel(bitmap,invert.xform(vec3(points[$-1].x, points[$-1].y, 0.)) ));
			// writefln("foo");

			while(points.length > 0){
				pkt = points[$-1];
				points.length = points.length - 1;
				if(pp[pkt.x - 1 + xResolution*pkt.y] == background && pkt.x > 0){
					points ~= point(pkt.x - 1, pkt.y);
					if(!interpolation)
						putPixel(surface, points[$-1], getPixel(bitmap,invert.xform(vec3(points[$-1].x, points[$-1].y, 0.)) ) );
					else
						putPixel(surface, points[$-1], getPixelInterp(bitmap,invert.xform(vec3(points[$-1].x, points[$-1].y, 0.)), bitmap.w, bitmap.h ) );
				}
				if(pp[pkt.x + 1 + xResolution*pkt.y] == background && pkt.x < xResolution - 1){
					points ~= point(pkt.x + 1, pkt.y);
					if(!interpolation)
						putPixel(surface, points[$-1], getPixel(bitmap,invert.xform(vec3(points[$-1].x, points[$-1].y, 0.)) ) );
					else
						putPixel(surface, points[$-1], getPixelInterp(bitmap,invert.xform(vec3(points[$-1].x, points[$-1].y, 0.)), bitmap.w, bitmap.h ) );
						
				}
				if(pp[pkt.x  + xResolution*(pkt.y - 1)] == background && pkt.y > 0){
					points ~= point(pkt.x , pkt.y -1);
					if(!interpolation)
						putPixel(surface, points[$-1], getPixel(bitmap,invert.xform(vec3(points[$-1].x, points[$-1].y, 0.)) ) );
					else
						putPixel(surface, points[$-1], getPixelInterp(bitmap,invert.xform(vec3(points[$-1].x, points[$-1].y, 0.)), bitmap.w, bitmap.h ) );
				}
				if(pp[pkt.x  + xResolution*(pkt.y + 1)] == background ){
					if(pkt.y < yResolution - 2)
					points ~= point(pkt.x , pkt.y +1);
					if(!interpolation)
						putPixel(surface, pkt.x, pkt.y+1, getPixel(bitmap,invert.xform(vec3(points[$-1].x, points[$-1].y, 0.)) ) );
					else
						putPixel(surface, points[$-1], getPixelInterp(bitmap,invert.xform(vec3(points[$-1].x, points[$-1].y, 0.)), bitmap.w, bitmap.h ) );
				}
			}
	}


}
